"""
地址解析模块
================

该模块负责解析各种格式的读取和写入地址，并将其转换为统一的内部表示形式。
"""


from typing import Any, Dict, List, Tuple, Union, Optional
from .typedef import AddressType, FullReadType, FullWriteType
from ..utils.logger import get_logger,default_logger


class AddressResolver:
    """地址解析器"""

    def __init__(self):
        """
        初始化地址解析器
        """
        self.logger = default_logger.getChild("AddressResolver")

    @staticmethod
    def resolve_read_address(address: FullReadType) -> Dict[str, Any]:
        """
        解析读取地址

        Args:
            address: 各种格式的读取地址参数

        Returns:
            Dict[str, Any]: 解析后的地址信息，包含:
                - addresses: 地址列表
                - address_count: 地址数量
                - data_types: 数据类型列表（如果提供）
                - options: 选项列表（如果提供）
                - lengths: 长度列表（如果提供）
        """
        logger = default_logger.getChild("AddressResolver")
        logger.debug(f"开始解析读取地址: {address}")

        result = {
            'addresses': [],
            'address_count': 0,
            'data_types': [],
            'options': [],
            'lengths': []
        }

        try:
            # 处理单个地址
            if isinstance(address, (str, int)):
                result['addresses'] = [address]
                result['address_count'] = 1
                logger.debug(f"单个地址解析完成: {result}")
                return result

            # 处理地址列表
            if isinstance(address, list):
                # 检查是否为元组列表（带数据类型）
                if all(isinstance(item, tuple) for item in address):
                    return AddressResolver._resolve_read_tuple_list(address, result)
                else:
                    # 普通地址列表
                    result['addresses'] = address
                    result['address_count'] = len(address)
                    logger.debug(f"地址列表解析完成: {result}")
                    return result

            # 处理字典配置
            if isinstance(address, dict):
                return AddressResolver._resolve_read_config_address(address, result)

            # 处理元组
            if isinstance(address, tuple):
                return AddressResolver._resolve_read_address_tuple(address, result)

            logger.debug(f"地址解析完成: {result}")
            return result

        except Exception as e:
            logger.error(f"解析读取地址时发生错误: {str(e)}", exc_info=True)
            raise

    @staticmethod
    def resolve_write_address(address: FullWriteType) -> Dict[str, Any]:
        """
        解析写入地址

        Args:
            address: 各种格式的写入地址参数

        Returns:
            Dict[str, Any]: 解析后的地址信息，包含:
                - addresses: 地址列表
                - values: 值列表
                - data_types: 数据类型列表（如果提供）
                - options: 选项列表（如果提供）
                - lengths: 长度列表（如果提供）
        """
        logger = default_logger.getChild("AddressResolver")
        logger.debug(f"开始解析写入地址: {address}")

        result = {
            'addresses': [],
            'values': [],
            'data_types': [],
            'options': [],
            'lengths': []
        }

        try:
            # 处理单个地址和值
            if isinstance(address, tuple) and len(address) == 2 and not isinstance(address[0], (list, tuple, dict)):
                result['addresses'].append(address[0])
                result['values'].append(address[1])
                logger.debug(f"单个地址元组解析完成: {result}")
                return result

            # 处理地址列表
            if isinstance(address, list):
                # 检查是否为字典列表
                if all(isinstance(item, dict) for item in address):
                    return AddressResolver._resolve_write_dict_list(address, result)
                # 检查是否为元组列表
                elif all(isinstance(item, tuple) for item in address):
                    return AddressResolver._resolve_write_tuple_list(address, result)
                else:
                    # 普通地址列表（这种情况在写入中较少见）
                    result['addresses'] = address
                    logger.debug(f"地址列表解析完成: {result}")
                    return result

            # 处理字典配置
            if isinstance(address, dict):
                return AddressResolver._resolve_write_config_address(address, result)

            # 处理元组
            if isinstance(address, tuple):
                return AddressResolver._resolve_write_address_tuple(address, result)

            # 处理单个地址（这种情况在写入中较少见）
            if isinstance(address, (str, int)):
                result['addresses'].append(address)
                logger.debug(f"单个地址解析完成: {result}")
                return result

            logger.debug(f"地址解析完成: {result}")
            return result

        except Exception as e:
            logger.error(f"解析写入地址时发生错误: {str(e)}", exc_info=True)
            raise

    @staticmethod
    def _resolve_read_address_tuple(address_tuple: Tuple, result: Dict[str, Any]) -> Dict[str, Any]:
        """
        解析读取地址元组

        Args:
            address_tuple: 地址元组
            result: 结果字典

        Returns:
            Dict[str, Any]: 解析后的地址信息
        """
        logger = default_logger.getChild("AddressResolver")
        # 处理元组格式 (address, data_type, ...)
        if len(address_tuple) >= 1:
            result['addresses'].append(address_tuple[0])
            result['address_count'] = 1

            # 处理数据类型
            if len(address_tuple) >= 2:
                result['data_types'].append(address_tuple[1])

            # 处理选项或长度
            if len(address_tuple) >= 3:
                third_element = address_tuple[2]
                # 判断第三个元素是选项还是长度
                if isinstance(third_element, str):
                    result['options'].append(third_element)
                else:
                    result['lengths'].append(third_element)

            # 处理第四个元素
            if len(address_tuple) >= 4:
                fourth_element = address_tuple[3]
                # 判断第四个元素是选项还是长度
                if isinstance(fourth_element, str):
                    result['options'].append(fourth_element)
                else:
                    result['lengths'].append(fourth_element)

        logger.debug(f"读取地址元组解析完成: {result}")
        return result

    @staticmethod
    def _resolve_read_tuple_list(address_list: List[Tuple], result: Dict[str, Any]) -> Dict[str, Any]:
        """
        解析读取元组列表

        Args:
            address_list: 元组列表
            result: 结果字典

        Returns:
            Dict[str, Any]: 解析后的地址信息
        """
        logger = default_logger.getChild("AddressResolver")
        for item in address_list:
            if len(item) >= 1:
                result['addresses'].append(item[0])

                # 处理数据类型
                if len(item) >= 2:
                    result['data_types'].append(item[1])

                # 处理选项或长度
                if len(item) >= 3:
                    third_element = item[2]
                    # 判断第三个元素是选项还是长度
                    if isinstance(third_element, str):
                        result['options'].append(third_element)
                    else:
                        result['lengths'].append(third_element)

        result['address_count'] = len(result['addresses'])
        logger.debug(f"读取元组列表解析完成: {result}")
        return result

    @staticmethod
    def _resolve_read_config_address(config: Dict[str, Any], result: Dict[str, Any]) -> Dict[str, Any]:
        """
        解析读取配置地址

        Args:
            config: 配置字典
            result: 结果字典

        Returns:
            Dict[str, Any]: 解析后的地址信息
        """
        logger = default_logger.getChild("AddressResolver")
        # 处理单个地址配置 {"address": "...", "data_type": "..."}
        if 'address' in config:
            result['addresses'] = [config['address']]
            result['address_count'] = 1
            if 'data_type' in config:
                result['data_types'].append(config['data_type'])
            if 'option' in config:
                result['options'].append(config['option'])
            if 'length' in config:
                result['lengths'].append(config['length'])
            logger.debug(f"读取单地址配置解析完成: {result}")
            return result

        # 处理批量地址配置 {"addresses": [...]}
        if 'addresses' in config:
            result['addresses'] = config['addresses']
            result['address_count'] = len(config['addresses'])

            # 处理统一数据类型
            if 'data_type' in config:
                result['data_types'].append(config['data_type'])

            # 处理多个数据类型
            if 'data_types' in config:
                result['data_types'] = config['data_types']

            if 'options' in config:
                result['options'] = config['options']
            if 'lengths' in config:
                result['lengths'] = config['lengths']
            logger.debug(f"读取批量地址配置解析完成: {result}")
            return result

        return result

    @staticmethod
    def _resolve_write_address_tuple(address_tuple: Tuple, result: Dict[str, Any]) -> Dict[str, Any]:
        """
        解析写入地址元组

        Args:
            address_tuple: 地址元组
            result: 结果字典

        Returns:
            Dict[str, Any]: 解析后的地址信息
        """
        logger = default_logger.getChild("AddressResolver")
        # 处理元组格式 (address, value, ...)
        if len(address_tuple) >= 2:
            result['addresses'].append(address_tuple[0])
            result['values'].append(address_tuple[1])

            # 处理数据类型
            if len(address_tuple) >= 3:
                result['data_types'].append(address_tuple[2])

            # 处理选项或长度
            if len(address_tuple) >= 4:
                fourth_element = address_tuple[3]
                # 判断第四个元素是选项还是长度
                if isinstance(fourth_element, str):
                    result['options'].append(fourth_element)
                else:
                    result['lengths'].append(fourth_element)

            # 处理第五个元素
            if len(address_tuple) >= 5:
                fifth_element = address_tuple[4]
                # 判断第五个元素是选项还是长度
                if isinstance(fifth_element, str):
                    result['options'].append(fifth_element)
                else:
                    result['lengths'].append(fifth_element)

        logger.debug(f"写入地址元组解析完成: {result}")
        return result

    @staticmethod
    def _resolve_write_dict_list(address_list: List[Dict], result: Dict[str, Any]) -> Dict[str, Any]:
        """
        解析写入字典列表

        Args:
            address_list: 字典列表
            result: 结果字典

        Returns:
            Dict[str, Any]: 解析后的地址信息
        """
        logger = default_logger.getChild("AddressResolver")
        for item in address_list:
            if 'address' in item and 'value' in item:
                result['addresses'].append(item['address'])
                result['values'].append(item['value'])

                if 'data_type' in item:
                    result['data_types'].append(item['data_type'])
                if 'option' in item:
                    result['options'].append(item['option'])
                if 'length' in item:
                    result['lengths'].append(item['length'])

        logger.debug(f"写入字典列表解析完成: {result}")
        return result

    @staticmethod
    def _resolve_write_tuple_list(address_list: List[Tuple], result: Dict[str, Any]) -> Dict[str, Any]:
        """
        解析写入元组列表

        Args:
            address_list: 元组列表
            result: 结果字典

        Returns:
            Dict[str, Any]: 解析后的地址信息
        """
        logger = default_logger.getChild("AddressResolver")
        for item in address_list:
            if len(item) >= 2:
                result['addresses'].append(item[0])
                result['values'].append(item[1])

                # 处理数据类型
                if len(item) >= 3:
                    result['data_types'].append(item[2])

                # 处理选项或长度
                if len(item) >= 4:
                    fourth_element = item[3]
                    # 判断第四个元素是选项还是长度
                    if isinstance(fourth_element, str):
                        result['options'].append(fourth_element)
                    else:
                        result['lengths'].append(fourth_element)

        logger.debug(f"写入元组列表解析完成: {result}")
        return result

    @staticmethod
    def _resolve_write_config_address(config: Dict[str, Any], result: Dict[str, Any]) -> Dict[str, Any]:
        """
        解析写入配置地址

        Args:
            config: 配置字典
            result: 结果字典

        Returns:
            Dict[str, Any]: 解析后的地址信息
        """
        logger = default_logger.getChild("AddressResolver")
        # 处理单个地址配置 {"address": "...", "value": "..."}
        if 'address' in config and 'value' in config:
            result['addresses'].append(config['address'])
            result['values'].append(config['value'])
            if 'data_type' in config:
                result['data_types'].append(config['data_type'])
            if 'option' in config:
                result['options'].append(config['option'])
            if 'length' in config:
                result['lengths'].append(config['length'])
            logger.debug(f"写入单地址配置解析完成: {result}")
            return result

        # 处理批量地址配置 {"addresses": [...], "values": [...]}
        if 'addresses' in config and 'values' in config:
            result['addresses'] = config['addresses']
            result['values'] = config['values']

            # 处理统一数据类型
            if 'data_type' in config:
                result['data_types'].append(config['data_type'])

            # 处理多个数据类型
            if 'data_types' in config:
                result['data_types'] = config['data_types']

            if 'options' in config:
                result['options'] = config['options']
            if 'lengths' in config:
                result['lengths'] = config['lengths']
            logger.debug(f"写入批量地址配置解析完成: {result}")
            return result

        # 如果配置字典本身就是地址映射 {"addr1": val1, "addr2": val2}
        if all(isinstance(key, (str, int)) and not isinstance(key, (list, dict)) for key in config.keys()):
            result['addresses'] = list(config.keys())
            result['values'] = list(config.values())
            logger.debug(f"写入地址映射配置解析完成: {result}")
            return result

        return result

    @staticmethod
    def apply_address_mapping(address_info: Dict[str, Any], mapping: Dict[str, Any]) -> Dict[str, Any]:
        """
        应用地址映射

        Args:
            address_info: 地址信息
            mapping: 地址映射配置

        Returns:
            Dict[str, Any]: 应用映射后的地址信息
        """
        # 如果没有提供映射，则直接返回原地址信息
        if not mapping:
            return address_info

        mapped_info = address_info.copy()
        mapped_addresses = []

        # 对每个地址应用映射
        for addr in address_info.get('addresses', []):
            # 如果地址在映射中，则使用映射后的地址
            if addr in mapping:
                mapped_addresses.append(mapping[addr])
            else:
                # 否则保持原地址
                mapped_addresses.append(addr)

        mapped_info['addresses'] = mapped_addresses

        # 如果是读取地址信息，更新地址计数
        if 'address_count' in mapped_info:
            mapped_info['address_count'] = len(mapped_addresses)

        return mapped_info